home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / pc / files / dsp / 56100tar.z / 56100tar / 56100 / g722 / h221fix / h221rx.asm next >
Encoding:
Assembly Source File  |  1992-04-15  |  51.8 KB  |  1,406 lines

  1. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ;;+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +
  3. ;;+ +                                        + +
  4. ;;+ +       Here starts the receive section of the H221 state machine        + +
  5. ;;+ +                                        + +
  6. ;;+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +
  7. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  8.  
  9.         list            ; receive state machine
  10.  
  11. ;;***********************************************************************
  12. ;;*                                    *
  13. ;;*    Bit Field State 0  :  This state is used when searching for     *
  14. ;;*    frame alignment either for the first time or when frame        *
  15. ;;*     alignment has been lost. As the data is being fed into        *
  16. ;;*    a0 MSB the frame alignment data will take the following        *
  17. ;;*    format :                            *
  18. ;;*                                    *
  19. ;;*            |             a0              |            *
  20. ;;*       ----->     1    1 0 1 1    0 0 0 0    0 0 0 0    0 0 0            *
  21. ;;*                                    *
  22. ;;*    The 7 MSB bits represent the correct frame alignment        *
  23. ;;*    sequence, i.e in hex 'd' and '8' for positive logic        *
  24. ;;*    and '2' and '6' for negative logic.                *
  25. ;;*                                    *
  26. ;;*    Date    :    1/10/90                        *
  27. ;;*    Version    :    1.0                        *
  28. ;;*                                    *
  29. ;;*                                    *
  30. ;;***********************************************************************
  31.  
  32. bf_state_0    move    #control_word,r2    ; control word ptr in r2
  33.         move    x:ir,a            ; latest receive byte in a1
  34.  
  35.         bfclr    #$ff00,x:(r2)        ; disable the receive CRC
  36.                         ; clear frame and multiframe
  37.                         ; alignment bits
  38.                         ; reset terminal alarm
  39.                         ; reset odd/even frame receive
  40.                         ; reset crc error
  41.                         ; enable rx
  42.  
  43.         move    a0,x:isdn_count_rx    ; reset isdn receive count
  44.         move    a0,x:crc_enable_cnt    ; crc enable & disable counts
  45.         move    a0,x:crc_disable_cnt
  46.         move    a0,x:mf_error_count    ; reset multiframe error count
  47.         move    a0,x:faw_error_count    ; reset frame error count
  48.  
  49.         move    x:bas_faw_0,a0        ; read next apps channel bit
  50.         asr    a            ; into previous word before test
  51.         move    a0,x:bas_faw_0        ; for frame alignment
  52.  
  53.         bftsth    #$d800,a0        ; test frame alignment high bits
  54.         bcc    <end_bf_0
  55.  
  56.         bftstl    #$2600,a0        ; and low bits
  57.         bcc    <end_bf_0
  58.  
  59.         move    #bf_state_1,r0        ; if faw word is detected
  60.                         ; prepare next state
  61.         movei    #7,x0            ; set isdn receive count to 7
  62.         move    x0,x:isdn_count_rx
  63.  
  64. end_bf_0    rts
  65.  
  66. ;;***********************************************************************
  67. ;;*                                    *
  68. ;;*    Bit field state 1  :  Once the initial frame alignment        *
  69. ;;*    has been achieved this routine is used to verify this        *
  70. ;;*    alignment, to store the BAS error correcting code and.        *
  71. ;;*    the first bit of the multiframe alignment word.            *
  72. ;;*    For correct frame alignment bit 2 of the current H221        *
  73. ;;*    word must be set                        *
  74. ;;*                                    *
  75. ;;*    Date    :    1/10/90                        *
  76. ;;*    Version    :    1.0                        *
  77. ;;*                                    *
  78. ;;***********************************************************************
  79.  
  80. bf_state_1     move    x:ir,a            ; continue reading AC data into
  81.         move    x:erc_faw_0,a0        ; erc_faw word until count
  82.         asr    a            ; indicates completion
  83.         move    a0,x:erc_faw_0
  84.  
  85.         move    x:isdn_count_rx,b    ; compare receive byte count
  86.         move    #95,x0            ; with 95 to ensure all 16 bits
  87.         cmp    x0,b            ; of erc_faw_0 data are present
  88.         blt    <end_bf_1
  89.  
  90.         move    #bf_state_0,r0        ; default, frame alignment not
  91.                         ; verified start search again
  92.         bftsth    #$0002,a0        ; test bit 2 of new faw to check
  93.         bcc    <end_bf_1        ; for frame alignment
  94.  
  95.         move    a0,b            ; move a0 into b for right shift
  96.         asr    b            ; read first bit of mf alignment
  97.         move    b0,x:mf_align_wrd    ; test word into its storage
  98.  
  99.         move    #bf_state_2,r0        ; next state of state machine
  100.                         ; is prepared
  101. end_bf_1    rts
  102.  
  103. ;;***********************************************************************
  104. ;;*                                    *
  105. ;;*    Bit field state 2  :  This routine is used to finally        *
  106. ;;*    verify the correct reception of the frame alignment         *
  107. ;;*    word. The alignment test is the same as that used in        *
  108. ;;*    bf_state_1                            *
  109. ;;*                                    *
  110. ;;*    Date    :    1/10/90                        *
  111. ;;*    Version    :    1.0                        *
  112. ;;*                                    *
  113. ;;***********************************************************************
  114.  
  115. bf_state_2     move    x:ir,a            ; keep reading AC data until
  116.         move    x:bas_faw_0,a0        ; receive byte count indicates
  117.         asr    a            ; completion
  118.         move    a0,x:bas_faw_0
  119.  
  120.         move    x:isdn_count_rx,b    ; compare receive byte count
  121.         move    #175,x0            ; with 175 to ensure all 16 bits
  122.         cmp    x0,b            ; of bas_faw_0 data are present
  123.         blt    <end_bf_2
  124.  
  125.         move    #bf_state_0,r0        ; default, frame alignment not
  126.         move    #control_word,r3    ; verified then start search
  127.                         ; again
  128.         bftsth    #$00d8,a0        ; check for reception of new
  129.         bcc    <end_bf_2        ; alignment word.
  130.                         ; control word pointer in r3
  131.         bftstl    #$0026,a0
  132.         bcc    <end_bf_2
  133.                         ; correct faw received then
  134.         bfset    #$2000,x:(r3)        ; set appropriate bit in
  135.                         ; control word
  136.         move    #bf_state_3,r0
  137.  
  138. end_bf_2    rts
  139.  
  140. ;;***********************************************************************
  141. ;;*                                    *
  142. ;;*    Bit field state 3 routine : This routine is the last in        *
  143. ;;*     the bit field test subroutines. It is used to validate        *
  144. ;;*    the multiframe alignment word as a final synchronisation    *
  145. ;;*    check for the H.221 protocol.                    *
  146. ;;*                                    *
  147. ;;*    Date    :    1/10/90                        *
  148. ;;*    Version    :    1.0                        *
  149. ;;*                                    *
  150. ;;***********************************************************************
  151.  
  152. bf_state_3    move    #rx_count_0,x1        ; memory store of mf alignment
  153.         move    x1,x:rx_count_ptr    ; odd frame counts. first word
  154.  
  155. state_3a    move    x:rx_count_ptr,r2
  156.         move    #bf_state_0,r0        ; default next state
  157.  
  158.         move    x:isdn_count_rx,a    ; check complete multiframe has
  159.         move    #1279,x0        ; passed. yes, then no mf
  160.         cmp    x0,a    x:(r2+1),x0    ; alignment in this position ==>
  161.         bge    <end_bf_3        ; begin frame alignment search
  162.                         ; again.
  163.         move    #state_3a,r0        ; new next state
  164.                         ; compare isdn count with mf
  165.         cmp    x0,a            ; bit position count, different
  166.         bne    <end_bf_3        ; then end state
  167.  
  168.         move    x:ir,a
  169.         move    x:mf_align_wrd,a0    ; move next bit of multiframe
  170.         asr    a    x:(r2)+,x0    ; alignment to store and update
  171.         move    a0,x:mf_align_wrd    ; reference count pointer
  172.  
  173.         bftsth    #$d000,a0        ; test correct bit format for
  174.         bcc    <end_bf_3        ; multiframe alignment
  175.  
  176.         bftstl    #$2c00,a0
  177.         bcc    <end_bf_3
  178.  
  179.         move    #smf_state_0,r0        ; new submultiframe state
  180.         move    #control_word,r3    ; control word pointer in r3
  181.         move    #first_rx,r2        ; set up ref. count for H221
  182.                         ; first pass
  183.         bfset    #$4000,x:(r3)        ; set multiframe alignment
  184.                         ; flag in control word
  185.         move    #880,x0            ; multiframe word successfully
  186.         move    x0,x:isdn_count_rx    ; detected, reset receive count
  187.                         ; to correct value
  188.         move    #bas_erc_faw,x0        ; set up initial ISDN receive
  189.         move    x0,x:bas_erc_faw_ptr    ; word pointer
  190.  
  191. end_bf_3    move    r2,x:rx_count_ptr
  192.  
  193.         rts
  194.  
  195.         list
  196.  
  197. ;;***********************************************************************
  198. ;;*                                    *
  199. ;;*    Submultiframe processing routine even : This routine is     *
  200. ;;*    used as a common starting point for every even            *
  201. ;;*    frame. For the initial frame 0 the routine re_initialises    *
  202. ;;*    the pointers and counts for the current multiframe.        *
  203. ;;*                                    *
  204. ;;*    Date     : 3/9/90                        *
  205. ;;*    Version    : 1.0                            *
  206. ;;*                                    *
  207. ;;***********************************************************************
  208.  
  209. smf_state_0    move    x:isdn_count_rx,b    ; test for end of previous
  210.         tst    b            ; multiframe, if not then            
  211.         bne    <smf_state_even        ; end
  212.         
  213.         move    #bas_erc_faw_ptr,r3    ; state pointer memory storage
  214.         move    #bas_erc_faw,x1        ; memory storage required for 
  215.         move    #rx_count,x0        ;
  216.                         ; +++++++++++++++++++++++++++++
  217.                         ;
  218.         move    x1,x:(r3)+        ; decoded_bas_ptr  ds    1
  219.         move    x0,x:(r3)        ; bas_erc_faw_ptr  ds    1
  220.                         ; rx_count_ptr       ds    1
  221.                         ;
  222.                         ; and ;
  223.                         ;
  224.                         ; decoded_bas       ds    8
  225.                         ; bas_erc_faw       ds    16
  226.                         ; 
  227.                         ;+++++++++++++++++++++++++++++++
  228. smf_state_even    move    x:rx_count_ptr,r2    ; restore pointers
  229.         move    x:bas_erc_faw_ptr,r3
  230.         
  231.         move    x:ir,a            ; read new isdn data
  232.         move    x:(r3),a0        ; H221 bit into a0 msb
  233.         asr    a    x:(r2)+n2,x0    ; and the current even frame
  234.                         ; H221 end count
  235.         cmp    x0,b    a0,x:(r3)+n3    ; compare count with preset 
  236.         blt    <end_state_even        ; value & finish if not complete
  237.                         ; and save new bas/erc/faw word
  238.         move    #control_word,r2    ; control word ptr in r2
  239.         move    #mf_count_state,r0    ; new next state
  240.         bfclr    #$1000,x:(r2)        ; clear even smf bit in control
  241.                         ; word
  242. end_state_even    rts
  243.  
  244. ;;***********************************************************************
  245. ;;*                                    *
  246. ;;*    Multiframe count state  :  This routine uses the H221 data    *
  247. ;;*    acquired during the last submultiframe even routine to         *
  248. ;;*    provide the latest multiframe count stored in bit 1 of         *
  249. ;;*    frames 0, 2, 4, 6, and bit 1 of frame 8 to indicate         *
  250. ;;*    whether multiframe counting is turned on or off.        *
  251. ;;*                                    *
  252. ;;*    Date     : 3/9/90                        *
  253. ;;*    Version    : 1.0                            *
  254. ;;*                                    *
  255. ;;***********************************************************************
  256.  
  257. mf_count_state    move    x:bas_erc_faw_ptr,r3    ; restore pointers
  258.         move    #bas_sort_state,r0    ; next state
  259.         
  260.         move    x:(r3),a        ; current H221 word pointer
  261.         move    x:mf_count_rx,a0    ; move latest multiframe count
  262.         asr    a            ; bit into storage word
  263.         move    a0,x:mf_count_rx
  264.         
  265.         rts
  266.  
  267. ;;***********************************************************************
  268. ;;*                                    *
  269. ;;*    Bit-rate Allocation Signal sort routine  : This routine uses    *  
  270. ;;*    the H221 data acquired during the last even state to sort the    *
  271. ;;*     BAS code for storage. The position of the bits are  ;        *
  272. ;;*                                    *
  273. ;;*    msb    <--------------------  a0  ------------------->        *
  274. ;;*                                    *
  275. ;;*        b  b  b  b  b  b  b  b     f  f  f  f  f     f  f  m        *
  276. ;;*        a  a  a  a  a  a  a  a     a  a  a  a  a    a  a  f        *
  277. ;;*        s  s  s  s  s  s  s  s     w  w  w  w  w  w  w        *
  278. ;;*                                     c        *
  279. ;;*        b  b  b  b  b  b  b  b      b  b  b  b  b     b  b  o        *
  280. ;;*        i  i  i  i  i  i  i  i     i  i  i  i  i     i  i  u        *
  281. ;;*        t  t  t  t  t  t  t  t      t  t  t  t  t     t  t  n        *
  282. ;;*                                  t        *
  283. ;;*        7  6  4  5  1  2  3  0     6  5  4  3  2    1  0  #        *
  284. ;;*                                    *
  285. ;;*    #     ==     count bits for frames 0,2,4,6            *
  286. ;;*             count enable bit frame 8            *
  287. ;;*                                    *
  288. ;;*    The position of the BAS bits after state execution will be :    *
  289. ;;*                                    *
  290. ;;*             <---------  Bas  Storage  --------->        *
  291. ;;*                                    *
  292. ;;*                        b b b b    b b b b            *
  293. ;;*              0 0 0 0 0 0 0 0   a a a a    a a a a            *
  294. ;;*                    s s s s    s s s s            *
  295. ;;*                                    *
  296. ;;*                    7 6 5 4    3 2 1 0            *
  297. ;;*                                    *
  298. ;;*    Date    :     3/9/90                        *
  299. ;;*    Version    :    1.0                        *
  300. ;;*                                    *
  301. ;;***********************************************************************
  302.  
  303. bas_sort_state    move    x:bas_erc_faw_ptr,r3
  304.         move    x:decoded_bas_ptr,r2    ; restore pointers
  305.  
  306.         clr    a    x:(r3)+,x0
  307.         bftsth    #$8000,x0        ; bas bit 7 test
  308.         rol    a            ; rotate carry into a1 lsb
  309.         bftsth    #$4000,x0        ; bas bit 6 test
  310.         rol    a            ; rotate carry into a1 lsb
  311.         bftsth    #$1000,x0        ; bas bit 5 test
  312.         rol    a            ; rotate carry into a1 lsb
  313.         bftsth    #$2000,x0        ; bas bit 4 test
  314.         rol    a            ; rotate carry into a1 lsb
  315.         bftsth    #$0200,x0        ; bas bit 3 test
  316.         rol    a            ; rotate carry into a1 lsb
  317.         bftsth    #$0400,x0        ; bas bit 2 test
  318.         rol    a            ; rotate carry into a1 lsb
  319.         bftsth    #$0800,x0        ; bas bit 1 test
  320.         rol    a            ; rotate carry into a1 lsb
  321.         bftsth    #$0100,x0        ; bas bit 0 test
  322.         rol    a            ; rotate carry into a1 lsb
  323.         move    a1,x:(r2)        ; store rearranged bas data
  324.  
  325.         move    #bas_for_erc,r0
  326.  
  327.         rts
  328.  
  329. ;;***********************************************************************
  330. ;;*                                    *
  331. ;;*    BAS for ERC sort routine  :         This routine uses the     *  
  332. ;;*    H221 data acquired during the last even state to sort the    *
  333. ;;*     BAS code for subsequent error correction using the double    *
  334. ;;*    error-correcting code. The position of the bits are  ;        *
  335. ;;*                                    *
  336. ;;*    msb    <--------------------  a0  ------------------->        *
  337. ;;*                                    *
  338. ;;*        b  b  b  b  b  b  b  b     f  f  f  f  f     f  f  m        *
  339. ;;*        a  a  a  a  a  a  a  a     a  a  a  a  a    a  a  f        *
  340. ;;*        s  s  s  s  s  s  s  s     w  w  w  w  w  w  w        *
  341. ;;*                                     c        *
  342. ;;*        b  b  b  b  b  b  b  b      b  b  b  b  b     b  b  o        *
  343. ;;*        i  i  i  i  i  i  i  i     i  i  i  i  i     i  i  u        *
  344. ;;*        t  t  t  t  t  t  t  t      t  t  t  t  t     t  t  n        *
  345. ;;*                                  t        *
  346. ;;*        7  6  4  5  1  2  3  0     6  5  4  3  2    1  0  #        *
  347. ;;*                                    *
  348. ;;*    #     ==     count bits for frames 0,2,4,6            *
  349. ;;*             count enable bit frame 8            *
  350. ;;*                                    *
  351. ;;*    The position of the BAS bits after state execution will be :    *
  352. ;;*                                    *
  353. ;;*             <--------  Bas Erc Storage  -------->        *
  354. ;;*                                    *
  355. ;;*                    b b b b    b b b b            *
  356. ;;*                  0 0 0 0    0 0 0 0 a a a a    a a a a            *
  357. ;;*                    s s s s    s s s s            *
  358. ;;*                                    *
  359. ;;*                    0 1 2 3    4 5 6 7            *
  360. ;;*                                    *
  361. ;;*    Date    :     3/9/90                        *
  362. ;;*    Version    :    1.0                        *
  363. ;;*                                    *
  364. ;;***********************************************************************
  365.  
  366. bas_for_erc    move    x:decoded_bas_ptr,r3    ; recall latest bas pointer
  367.         move    #crc_bit_sort,r0    ; next state
  368.  
  369.         clr    a    x:(r3)+,b    ; clear a, 
  370.                         ; get latest BAS word in b
  371.         do    #8,bas_re_org
  372.         
  373.         ror    b            ; BAS bit into carry and then
  374.         rol    a            ; carry into a1 lsb
  375.         
  376. bas_re_org    move    a1,x:bas_erc_store    ; store rearranged bas data
  377.         
  378.         rts
  379.  
  380. ;;***********************************************************************
  381. ;;*                                    *
  382. ;;*    CRC Bit Sort Routine  :  This routine takes the CRC data    *
  383. ;;*    generated by the last CRC pass and sorts it into a form        *
  384. ;;*     which makes it easy to perform the comparison between this    *
  385. ;;*    data and the CRC bits transmitted in the next odd         *
  386. ;;*    submultiframe                            *
  387. ;;*                                    *
  388. ;;*    Date    :    12/9/90                        *
  389. ;;*    Version    :    1.0                        *
  390. ;;*                                    *
  391. ;;***********************************************************************
  392.  
  393. crc_bit_sort    move    x:rx_crc_data,a        ; get latest local CRC data
  394.         clr    b            ; clear b for storage
  395.         asr4    a            ; shift crc bits into 4 lsb's
  396.         
  397.         do    #4,crc_bit_re_org
  398.         
  399.         ror    a            ; shift crc bit into carry and 
  400.         rol    b            ; then into b1 lsb
  401.  
  402. crc_bit_re_org    move    b1,x:rx_crc_data    ; store masked CRC data
  403.  
  404.         move    #term_alarm_test,r0    ; Terminal alarm check state
  405.  
  406.         rts
  407.  
  408. ;;***********************************************************************
  409. ;;*                                    *
  410. ;;*    Terminal Alarm test state   :   This state tests bit 1 of    *
  411. ;;*    frame 14. If set then the transmitting terminal is in a        *
  412. ;;*    state of alarm.                         *
  413. ;;*                                    *
  414. ;;*    Date    :     1/10/90                        *
  415. ;;*    Version    :    1.2                        *
  416. ;;*                                    *
  417. ;;***********************************************************************
  418.  
  419. term_alarm_test    move    x:bas_erc_faw_ptr,r3    ; restore pointer
  420.         move    x:rx_count_ptr,r2    ; compare count with that
  421.         move    #1135,x0        ; of the first bit in frame 14
  422.         move    x:(r2),b        
  423.         move    #control_word,r2    ; control word pointer in r2
  424.         cmp    x0,b    x:(r3)+,y0    ; update bas/erc/faw rx pointer    
  425.         bne    <end_alarm_state    ; If frame ref. count is 
  426.                         ; not equal to 1135, exit state
  427.         bfclr    #$8000,x:(r2)        ; default, clear alarm bit
  428.         bftsth    #$0001,y0         ; test alarm bit
  429.         bcc    <end_alarm_state    ; no alarm then exit state
  430.  
  431.         bfset    #$8000,x:(r2)        ; there is an alarm so set
  432.                         ; the alarm bit
  433. end_alarm_state    move    #smf_odd_state,r0    ; all even state processing done                        ; go to odd submultiframe state
  434.         move    r3,x:bas_erc_faw_ptr    ; store updated pointer
  435.         
  436.         rts                
  437.  
  438. ;;***********************************************************************
  439. ;;*                                    *
  440. ;;*    SMF odd state routine  :  This routine is used to acquire    *
  441. ;;*    the odd frame H221 protocol data. The data is stored in a    *
  442. ;;*    location pointed to by a stored address value.            *
  443. ;;*                                    *
  444. ;;*    Date    :     3/9/90                        *
  445. ;;*    Version    :    1.0                        *
  446. ;;*                                    *
  447. ;;***********************************************************************
  448.  
  449. smf_odd_state    move    x:rx_count_ptr,r2    ; restore pointers
  450.         move    x:bas_erc_faw_ptr,r3
  451.  
  452.         move    x:isdn_count_rx,b    ; current isdn count in b
  453.         move    x:ir,a            ; current isdn rx byte in a 
  454.         move    x:(r3),a0        ; current bas word in a0
  455.         asr    a    x:(r2+9),x0    ; new H221 bit in old H221 word,
  456.                         ; end of odd H221 fm count in x0
  457.                         ; store new H221 data
  458.         cmp    x0,b    a0,x:(r3)+    ; end of odd frame H221 bits ?
  459.         blt    <end_odd_state        ; no, then branch
  460.         
  461.         move    #control_word,r2    ; get control word ptr in r2    
  462.         move    #faw_check_state,r0    ; H221 acquisition is complete,
  463.         bfset    #$1000,x:(r2)        ; new state pointed to by r0
  464.                         ; set odd smf bit in control
  465. end_odd_state    rts                ; word
  466.     
  467. ;;****************************************************************************
  468. ;;*                                         *
  469. ;;*    Frame Alignment check state  :  this state checks the latest odd     *
  470. ;;*    and even frames for correct frame alignment. If three consecutive    *
  471. ;;*    alignment errors occur the search for frame alignment begins again   *
  472. ;;*    at bit_field_state_0.                             *
  473. ;;*                                         *
  474. ;;*     The position of the bits are  ;                         *
  475. ;;*                                         *
  476. ;;*        msb    <--------------------  a0  ------------------->         *
  477. ;;*                                         *
  478. ;;*            b  b  b  b  b  b  b  b     f  f  f  f  f     f  f  m         *
  479. ;;*            a  a  a  a  a  a  a  a     a  a  a  a  a    a  a  f         *
  480. ;;*            s  s  s  s  s  s  s  s     w  w  w  w  w  w  w         *
  481. ;;*                                         c         *
  482. ;;*            b  b  b  b  b  b  b  b      b  b  b  b  b     b  b  o         *
  483. ;;*            i  i  i  i  i  i  i  i     i  i  i  i  i     i  i  u         *
  484. ;;*            t  t  t  t  t  t  t  t      t  t  t  t  t     t  t  n         *
  485. ;;*                                      t         *
  486. ;;*            7  6  4  5  1  2  3  0     6  5  4  3  2    1  0  #         *
  487. ;;*                                         *
  488. ;;*    Date     :    4/9/90                             *
  489. ;;*    Version    :    1.0                             *
  490. ;;*                                         *
  491. ;;****************************************************************************
  492.  
  493. faw_check_state    move    x:bas_erc_faw_ptr,r2    ; restore pointer
  494.         move    x:faw_error_count,b    ; faw error incremental counter
  495.                         ; in b
  496.         inc24    b    x:(r2-1),a    ; increment faw error count as  
  497.                         ; default & update ptr address
  498.         bftsth    #$00d8,a1        ; test even faw high bits
  499.         bcc    <faw_not_ok
  500.         bftstl    #$0026,a1        ; test even faw low bits
  501.         bcc    <faw_not_ok
  502.         bftsth    #$0002,x:(r2)        ; test bit 2 in current odd 
  503.         bcc    <faw_not_ok        ; frame, if ok then pass
  504.         
  505.         clr    b            ; if faw ok, clear consecutive
  506.                         ; error count
  507. faw_not_ok    move    b,x:faw_error_count    ; store new error count
  508.         move    #mf_align_chck_1,r0    ; default next state
  509.         
  510.         movei    #3,x0
  511.         cmp    x0,b            ; has error count reached 3 ?
  512.         blt    <not_3_consec        ; if not, then pass
  513.  
  514.         move    #bas_revert,r0        ; if 3 consecutive errors search
  515.                         ; for frame alignment begins
  516. not_3_consec    rts                ; again        
  517.  
  518.  
  519. ;;****************************************************************************
  520. ;;*                                         *
  521. ;;*    Multiframe Alignment Check Routine  :  This routine obtains         *
  522. ;;*    the multiframe alignment bits from each odd frame and after         *
  523. ;;*    completion, at the isdn reference count of #895, goes to state          *
  524. ;;*    mf_align_check2 to complete test for proper multiframe alignment.    *
  525. ;;*    If 3 consecutive alignment errors occur, the search for    both frame   *
  526. ;;*    and multiframe alignment occurs once more in bit_field_state_0         *
  527. ;;*                                         *
  528. ;;*    Date    :    4/9/90                             *
  529. ;;*    Version    :    1.0                             *
  530. ;;*                                         *
  531. ;;****************************************************************************
  532.  
  533. mf_align_chck_1    move    x:rx_count_ptr,r2
  534.         move    x:bas_erc_faw_ptr,r3    ; restore pointers
  535.         move    #erc_sort_state,r0    ; next state
  536.  
  537.         move    x:(r3),a        ; get latest H221 word
  538.         move    x:mf_align_wrd,a0    ; shift in the latest mf
  539.         asr    a    x:(r2)+,b    ; alignment bit into a0
  540.         move    a0,x:mf_align_wrd    ; and update pointer
  541.         
  542.         move    #815,x0            ; has complete multiframe 
  543.         cmp    x0,b            ; alignment word been             
  544.         bne    <end_mf_check1        ; collected
  545.         
  546.         move    #mf_align_chck_2,r0    ; new next state if compare 
  547.                         ; true
  548. end_mf_check1    move    r2,x:rx_count_ptr    ; store updated pointer
  549.  
  550.         rts
  551.  
  552. ;;***********************************************************************
  553. ;;*                                    *
  554. ;;*    Multiframe error check routine  :  this routine compares the     *
  555. ;;*    received multiframe bits with the alignment signal and sets    *
  556. ;;*    the mf_align_bit in the control word appropriately.        *
  557. ;;*                                    *
  558. ;;*    Date    :    12/9/90                        *
  559. ;;*    Version    :    1.0                        *
  560. ;;*                                    *
  561. ;;***********************************************************************
  562.  
  563. mf_align_chck_2    move    #mf_error_count,r3    
  564.         move    #erc_sort_state,r0    ; new next state
  565.         move    #control_word,r2    ; control word pointer in r2
  566.         
  567.         move    x:(r3),b        ; recall current multiframe
  568.                         ; error count
  569.         move    x:mf_align_wrd,a    ; latest multiframe alignment
  570.         inc24    b            ; bits in a and increment error
  571.                         ; count for default
  572.         bftsth    #$d000,a1        ; test for correct alignment
  573.         bcc    <mf_align_error        ; '1' bits
  574.         bftstl    #$2c00,a1        ; test for correct alignment
  575.         bcc    <mf_align_error        ; '0' bits
  576.  
  577.         clr    b            ; if correct alignment then
  578.                         ; clear error count
  579. mf_align_error    bfset    #$4000,x:(r2)        ; set multiframe alignment bit
  580.                         ; in control word as default
  581.         movei    #3,x0            ; test incremental error count
  582.         cmp    x0,b    b,x:(r3)+n3    ; and save it
  583.         blt    <end_mf_state2        ; if 3 or more, reset alignment
  584.         
  585.         bfclr    #$4000,x:(r2)        ; if no alignment then clear     
  586.         move    x0,x:(r3)        ; alignment bit in control word
  587.                         ; & limit error count to 3
  588. end_mf_state2    rts
  589.  
  590. ;;***********************************************************************
  591. ;;*                                    *
  592. ;;*    Error Code Sort routine  :  This routine is used for         *
  593. ;;*    sorting the bit rate allocation signal error correcting        *
  594. ;;*    code. The position of the bits are :                *
  595. ;;*                                    *
  596. ;;*    msb    <--------------------- a0 -------------------->        *
  597. ;;*                                    *
  598. ;;*        e  e  e     e  e  e  e  e     c  c  c  c  e    b  f  m        *
  599. ;;*        r  r  r     r  r  r  r  r     r  r  r  r  r    i  a  f        *
  600. ;;*        c  c  c     c  c  c  c  c     c  c  c  c  r     t  w          *
  601. ;;*                             o          a        *
  602. ;;*        b  b  b     b  b  b  b  b     b  b  b  b  r    A  b  l        *
  603. ;;*        i  i  i     i  i  i  i  i     i  i  i  i         i  i        *
  604. ;;*        t  t  t     t  t  t  t  t     t  t  t  t  b       t  g        *
  605. ;;*                             i          n        *
  606. ;;*        7  6  5     3  4  0  1  2     4  3  2  1  t       8  #            *
  607. ;;*                                    *
  608. ;;*    # == bit 1 of frames 1,3,5,7,9,11                *
  609. ;;*                                    *
  610. ;;*    The position of the BAS ERC bits before storage         *
  611. ;;*    will be :                            *
  612. ;;*                                    *
  613. ;;*          <-------  Bas/Erc  Storage  -------->            *
  614. ;;*                                    *
  615. ;;*          b b b b   b b    b b   e e e e    e e e e            *
  616. ;;*          a a a a   a a a a   r r r r    r r r r            *
  617. ;;*          s s s    s   s s    s s   c c c c     c c c c            *
  618. ;;*                                    *
  619. ;;*          0 1 2    3   4 5    6 7   0 1 2 3    4 5 6 7            *
  620. ;;*                                    *
  621. ;;*    Date    :    4/9/90                        *
  622. ;;*    Version    :    1.0                        *
  623. ;;*                                    *
  624. ;;***********************************************************************
  625.         
  626. erc_sort_state    move    x:bas_erc_faw_ptr,r3
  627.         move    x:bas_erc_store,a
  628.         
  629.         bftsth    #$0400,x:(r3)        ; erc bit 0 test
  630.         rol    a            ; rotate carry into a1 lsb
  631.         bftsth    #$0200,x:(r3)        ; erc bit 1 test
  632.         rol    a            ; rotate carry into a1 lsb
  633.         bftsth    #$0100,x:(r3)        ; erc bit 2 test
  634.         rol    a            ; rotate carry into a1 lsb
  635.         bftsth    #$1000,x:(r3)        ; erc bit 3 test
  636.         rol    a            ; rotate carry into a1 lsb
  637.         bftsth    #$0800,x:(r3)        ; erc bit 4 test
  638.         rol    a            ; rotate carry into a1 lsb
  639.         bftsth    #$2000,x:(r3)        ; erc bit 5 test
  640.         rol    a            ; rotate carry into a1 lsb
  641.         bftsth    #$4000,x:(r3)        ; erc bit 6 test
  642.         rol    a            ; rotate carry into a1 lsb
  643.         bftsth    #$8000,x:(r3)        ; erc bit 7 test
  644.         rol    a            ; rotate carry into a1 lsb
  645.         move    a1,x:bas_erc_store    ; re-store rearranged 
  646.                         ; bas/erc data
  647.         move    #crc_sort_2,r0        ; next state
  648.         
  649.         rts
  650.         
  651. ;;***************************************************************************
  652. ;;*                                        *
  653. ;;*    CRC Sort 2 routine  :  This routine is used to sort the received    *
  654. ;;*    CRC bits in the odd frames prior to comparing with the locally         *
  655. ;;*    generated CRC bits.  The position of the latest isdn bits are :        *
  656. ;;*                                        *
  657. ;;*    msb    <--------------------- a0 -------------------->            *
  658. ;;*                                        *
  659. ;;*        e  e  e     e  e  e  e  e     c  c  c  c  e    b  f  m            *
  660. ;;*        r  r  r     r  r  r  r  r     r  r  r  r  r    i  a  f            *
  661. ;;*        c  c  c     c  c  c  c  c     c  c  c  c  r     t  w              *
  662. ;;*                             o          a            *
  663. ;;*        b  b  b     b  b  b  b  b     b  b  b  b  r    A  b  l            *
  664. ;;*        i  i  i     i  i  i  i  i     i  i  i  i         i  i            *
  665. ;;*        t  t  t     t  t  t  t  t     t  t  t  t  b       t  g            *
  666. ;;*                             i          n            *
  667. ;;*        7  6  5     3  4  0  1  2     4  3  2  1  t       8  #                *
  668. ;;*                          *                *
  669. ;;*    # == bit 1 of frames 1,3,5,7,9,11                    *
  670. ;;*    * == msb                                *
  671. ;;*                                        *
  672. ;;*    Date     :    14/9/90                            *
  673. ;;*    version    ;    1.0                            *
  674. ;;*                                        *
  675. ;;***************************************************************************
  676.  
  677. crc_sort_2    move    x:bas_erc_faw_ptr,r3
  678.         move    #crc_en_disen_state,r0    ; next state
  679.         
  680.         move    x:(r3),a        ; latest isdn received data
  681.         asr4    a            ; shift crc bits into lsb's
  682.         movei    #15,x0            ; mask in x0
  683.         and    x0,a            ; clear unnecessary bits
  684.  
  685.         move    a1,x:crc_sorted        ; save sorted crc bits
  686.  
  687.         rts
  688.  
  689. ;;*****************************************************************************
  690. ;;*                                          *
  691. ;;*    CRC disable/enable check state  :  This state checks the received     *
  692. ;;*    CRC bits for disabling or enabling before entering the CRC test state.*
  693. ;;*    The position of the latest isdn bits are :                  *
  694. ;;*                                          *
  695. ;;*    msb    <--------------------- a0 -------------------->              *
  696. ;;*                                          *
  697. ;;*        e  e  e     e  e  e  e  e     c  c  c  c  e    b  f  m              *
  698. ;;*        r  r  r     r  r  r  r  r     r  r  r  r  r    i  a  f              *
  699. ;;*        c  c  c     c  c  c  c  c     c  c  c  c  r     t  w                *
  700. ;;*                             o          a              *
  701. ;;*        b  b  b     b  b  b  b  b     b  b  b  b  r    A  b  l              *
  702. ;;*        i  i  i     i  i  i  i  i     i  i  i  i         i  i              *
  703. ;;*        t  t  t     t  t  t  t  t     t  t  t  t  b       t  g              *
  704. ;;*                             i          n              *
  705. ;;*        7  6  5     3  4  0  1  2     4  3  2  1  t       8  #                  *
  706. ;;*                          *                  *
  707. ;;*    # == bit 1 of frames 1,3,5,7,9,11                      *
  708. ;;*    * == msb                                  *
  709. ;;*                                          *
  710. ;;*    Date    :     14/9/90                              *
  711. ;;*    Version    :    1.0                              *
  712. ;;*                                          *
  713. ;;*****************************************************************************
  714.  
  715. crc_en_disen_state move    #control_word,r2
  716.         move    x:bas_erc_faw_ptr,r3
  717.         bftsth    #$0400,x:(r2)
  718.         bcs    <crc_enabled
  719.  
  720. ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  721.  
  722.         move    #crc_test_count,r0    ; crc count pointer in r0
  723.         move    x:crc_enable_cnt,b    ; get latest crc enabling count
  724.         inc24     b     b0,x:(r0)+    ; inc it & clear crc test count
  725.         clr    a    b0,x:(r0)+    ; clear a & crc error count
  726.  
  727.         bftsth    #$00f0,x:(r3)        ; all crc bits received '1' ?
  728.         tcs    a,b            ; yes, crc still disabled
  729.                         ; ==> clear b
  730.         move    b,x:crc_enable_cnt    ; store modified disable count
  731.         move    #error_calc_1,r0    ; next state
  732.         movei    #2,y1
  733.         cmp    y1,b            ; has the count reached 2 ?
  734.           blt    <end_check_state    ; no, then do nothing, crc not
  735.                         ; enabled.
  736.         bfset    #$0400,x:(r2)        ; yes, set crc enabled bit in
  737.         move    b0,x:crc_enable_cnt    ; control word & clear enbl cnt
  738.         move    #crc_test_state,r0    ; new next state
  739.  
  740.         bra    <end_check_state    ; now finish state
  741.  
  742. ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  743.  
  744. crc_enabled    move    #crc_test_state,r0    ; default next state
  745.         move    x:crc_disable_cnt,b    ; get latest crc disable count
  746.         inc24    b    b0,y0        ; increment it, set y0 to 0
  747.  
  748.         bftsth    #$00f0,x:(r3)        ; test crc bits for disable
  749.         tcc    y0,b            ; some '0's received ? yes
  750.                         ; then clear disable count
  751.         move    b,x:crc_disable_cnt    ; store the modified reference
  752.         movei    #8,y1
  753.         cmp    y1,b            ; count, has it reached 8 ?
  754.         blt    <end_check_state    ; if not then exit state
  755.  
  756.         move    #error_calc_1,r0    ; if yes, then new next state,
  757.         bfclr    #$0c00,x:(r2)        ; set crc disabled bit in
  758.         move    b0,x:crc_disable_cnt    ; control word, clear rx error
  759.                         ; bit & crc disable count.
  760.  
  761. ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  762.  
  763. end_check_state    rts
  764.  
  765. ;;***********************************************************************
  766. ;;*                                    *
  767. ;;*    CRC test state    :  This state is used to compare the received    *
  768. ;;*    CRC data with that generated locally.  It also calculates the     *
  769. ;;*    number of errors received in the last 100 blocks. If this     *
  770. ;;*     number exceeds 89 then the search for frame alignment is     *
  771. ;;*    re-initiated from bit_field_state_0.                *
  772. ;;*                                    *
  773. ;;*    Date    :    14/9/90                        *
  774. ;;*    Version    :    1.0                        *
  775. ;;*                                    *
  776. ;;***********************************************************************
  777.  
  778. crc_test_state    move    #crc_test_count,r2    ; **** x memory partitiion ****
  779.         move    #error_calc_1,r0    ;
  780.         move    #control_word,r3    ; crc_test_count    ds    1
  781.                         ; crc_error_count   ds    1
  782.                         ; end_count          dc    100
  783.                         ; test_error_count  dc    89
  784.                         ; crc_sorted        ds    1
  785.                         ;
  786.                         ;******************************
  787.         move    x:(r2+4),b        ; get latest received crc bits
  788.         move    x:rx_crc_data,x0    ; get latest locally generated
  789.                         ; crc bits
  790.         bfclr    #$0800,x:(r3)        ; clear crc error flag in
  791.                         ; control word as default
  792.         cmp    x0,b    x:(r2+1),a    ; crc_error_count in a
  793.         beq    <crc_ok            ; compare both sets of crc bits
  794.                         ; if the same then, O.K.
  795.         bfset    #$0800,x:(r3)        ; if different, set crc error
  796.         inc24    a            ; flag in control word and
  797.                         ; increment error count
  798. crc_ok        move    x:(r2),b        ; get latest crc test count
  799.         inc24    b    a,x:(r2+1)    ; increment it, and store
  800.                         ; latest updated error count
  801.         move    x:(r2+2),x0        ; & max. reference count in x0
  802.         cmp    x0,b    b,x:(r2)+n2    ; compare current count with
  803.         blt    <crc_check_done        ; max. and store updated count
  804.  
  805.         move    a0,x:(r2)        ; clear test count
  806.         move    x:(r2+3),x0        ; get error compare value of 89
  807.         cmp    x0,a    a0,x:(r2+1)    ; compare actual error count
  808.         ble    <crc_check_done        ; with stored max. & reset
  809.                         ; error count
  810.         move    #bas_revert,r0        ; if the actual error count is
  811.                         ; > 89 then start search for
  812. crc_check_done    rts                ; frame alignment once more.
  813.  
  814. ;;****************************************************************************
  815. ;;*                                         *
  816. ;;*    Error Calc State 1    :     This state takes the latest         *
  817. ;;*    rearranged bas data and calculates the ERROR bits from transmission  *
  818. ;;*    The structure used is as indicated below :                 *
  819. ;;*                                         *
  820. ;;*                 b b b b     b b b b       e e e e    e    e e e         *
  821. ;;*                 a a a a     a a a a       r r r r    r    r r r         *
  822. ;;*    y y y y   y y y    y    s s s s    s s s s    c c c c    c    c c c         *
  823. ;;*                                         *
  824. ;;*    8 7 6 5   4 3 2    1    0 1 2 3    4 5 6 7       0 1 2 3    4    5 6 7         *
  825. ;;*                                         *
  826. ;;*    <----   a1   ---->   <---------------   a0   --------------->           *
  827. ;;*                                         *
  828. ;;*    For the correct polynomial division (i.e. generator polynomial         *
  829. ;;*    g(x) == x8 + x7 + x6 + x4 + x2 + x + 1) the equations required are   *
  830. ;;*                                         *
  831. ;;*    +  == modulo 2 addition        @ y1 == y8 + bas 0             *
  832. ;;*    @  == next clock value        @ y2 == y8 + y1                 *
  833. ;;*    y8 == output            @ y3 == y8 + y2                 *
  834. ;;*                    @ y5 == y8 + y4                 *
  835. ;;*                    @ y7 == y8 + y6                 *
  836. ;;*                    @ y8 == y8 + y7                 *
  837. ;;*                                         *
  838. ;;*    Date    :    2/10/90 & 12/10/90                     *
  839. ;;*    Version    :    1.0 & 1.1                         *
  840. ;;*                                         *
  841. ;;****************************************************************************
  842.  
  843. error_calc_1    move    #bas_erc_store,r2
  844.         move    #error_calc_2,r0
  845.         move    r2,x:(r2+7)        ; store pointer
  846.         move    x:(r2),a        ; set up a accumulator for erc
  847.                         ; bit evaluation
  848.         move    a0,x:(r2+4)        ; clear reference count
  849.         move    a0,x:(r2+5)        ; store a accumulator set-up
  850.         move    a1,x:(r2+6)        ; for next state
  851.  
  852.         rts
  853.  
  854. error_calc_2    move    x:r2_temp_2,r2        ; recall pointer
  855.                         ; The storage structure used
  856.                         ; for this routine is as below
  857.                         ; ******************************
  858.                         ;
  859.                         ; bas_erc_store    ds    1
  860.                         ; mask        dc    $00d7
  861.                         ; error_ref_val    dc    0
  862.                         ;        dc    16
  863.                         ; count_check    ds    1
  864.                         ; temp_error    ds    2
  865.                         ; r2_temp_2    ds    1
  866.                         ; error_store    ds    1
  867.                         ;
  868.                         ;*******************************
  869.         clr    a            ; clear accumulators for loop
  870.         clr    b    x:(r2+1),x0    ; load generator polynomial mask
  871.                         ; into x0
  872.         move    x:(r2+5),a1        ; restore crc division data into
  873.         move    x:(r2+6),a0        ; accumulator a
  874.  
  875.         bfclr    #$0080,a1        ; test last output bit, result
  876.         tcc    x0,b            ; sets current mask in b.
  877.         asl    a    b,y1        ; shift crc before eor'ing, and
  878.                         ; new mask in y1
  879.         eor    y1,a    x:(r2+4),b    ; update crc storage bits and
  880.                         ; get loop count value in b
  881.         move    x:(r2+3),y0        ; max. loop count of 16 in y0
  882.         move    a1,x:(r2+5)        ; store crc division data into
  883.                         ; memory
  884.         inc24    b    a0,x:(r2+6)    ; inc. loop count, compare with
  885.          cmp    y0,b    b,x:(r2+4)    ; max. and save updated count
  886.         blt    <end_error_calc        ; if not complete, repeat state
  887.  
  888.         move    a1,x:(r2+8)        ; store calculated ERC bits
  889.         move    #bas_error_fix_1,r0    ; new next state pointer
  890.  
  891. end_error_calc    rts
  892.  
  893. ;;***********************************************************************
  894. ;;*                                    *
  895. ;;*    BAS Error Correct Routines    :    These routines take    *
  896. ;;*    the error correcting data generated from the last routine    *
  897. ;;*    and subsequently correct the latest received BAS signal.    *
  898. ;;*                                    *
  899. ;;*    Date    :    2/10/90                        *
  900. ;;*    Version    :    1.0                        *
  901. ;;*                                    *
  902. ;;***********************************************************************
  903.  
  904. bas_error_fix_1    move    #single_error,r0    ; single error check remainders
  905.         move    x:error_store,b        ; latest error remainder result
  906.         clr    a    b,y0        ; clear a for loop, ensure y0 is
  907.                         ; not empty if error present
  908.         tst    b    x:(r0)+,x0    ; check for received errors and
  909.         beq    <no_bas_error        ; load first ref. in x0 whilst
  910.                         ; updating remainder pointer
  911.         do     #8,bas_fix_lp_1        ; repeat loop for all possible
  912.                         ; single error remainders
  913.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  914.                         ; and get new remainder in x0
  915.         teq    y0,a    r0,r2        ; if equal make sure a is not
  916.                         ; cleared and store remainder
  917.                         ; pointer value
  918. bas_fix_lp_1    move    #bas_error_fix_2,r0    ; default next state
  919.         tst    a    x:(r2+6),a    ; has error been located ?
  920.                         ; put error correct mask in a
  921.         beq    <end_check_1        ; if a is clear error not found
  922.                         ; go to next search state
  923. no_bas_error    move    #bas_valid_tst_0,r0    ; no error or error found
  924.                         ; then next state is this
  925.         move    a1,x:error_mask        ; store relevant error correct
  926.                         ; mask
  927. end_check_1    rts
  928.  
  929. ;;+++++++++++++++++++++++++++++++++++++++++++++++
  930.  
  931. bas_error_fix_2    move    #double_error_0,r0    ; double error check remainders
  932.         move    x:error_store,b        ; latest error remainder result
  933.         clr    a    b,y0        ; clear a for loop and ensure
  934.                         ; y0 is not empty.
  935.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  936.                         ; updating the remainder pointer
  937.         do     #7,bas_fix_lp_2        ; repeat loop for all possible
  938.                         ; single error remainders
  939.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  940.                         ; and put new remainder in x0
  941.         teq    y0,a    r0,r2        ; if equal, make sure a is not
  942.                         ; cleared and store remainder
  943.                         ; pointer value
  944. bas_fix_lp_2    move    #bas_error_fix_3,r0    ; default next state
  945.         tst    a    x:(r2+5),a    ; has error been located ?
  946.                         ; put error correct mask in a
  947.         beq    <end_check_2        ; if a is clear, error not found
  948.                         ; go to next search state
  949.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  950.                         ; state
  951.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  952. end_check_2    rts
  953.  
  954. ;;+++++++++++++++++++++++++++++++++++++++++++++++
  955.  
  956. bas_error_fix_3    move    #double_error_1,r0    ; double error check remainders
  957.         move    x:error_store,b        ; latest error remainder result
  958.         clr    a    b,y0        ; clear a for loop and ensure y0
  959.                         ; is not empty.
  960.         move    x:(r0)+,x0        ; load first ref. in x0 whilst 
  961.                         ; updating the remainder pointer
  962.         do     #7,bas_fix_lp_3        ; repeat loop for all possible
  963.                         ; single error remainders
  964.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  965.                         ; and get new remainder in x0
  966.         teq    y0,a    r0,r2        ; if equal, make sure a is not 
  967.                         ; cleared and store remainder
  968.                         ; pointer value
  969. bas_fix_lp_3    move    #bas_error_fix_4,r0    ; default next state    
  970.         tst    a    x:(r2+5),a    ; has error been located ?
  971.                         ; put error correct mask in a
  972.         beq    <end_check_3        ; if a is clear, error not found
  973.                         ; go to next search state
  974.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  975.                         ; state
  976.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  977. end_check_3    rts
  978.         
  979. ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  980.  
  981. bas_error_fix_4    move    #double_error_2,r0    ; double error check remainders
  982.         move    x:error_store,b        ; latest error remainder result
  983.         clr    a    b,y0        ; clear a for loop and ensure y0
  984.                         ; is not empty.
  985.         move    x:(r0)+,x0        ; load first ref. in x0 whilst 
  986.                         ; updating the remainder pointer
  987.         do     #7,bas_fix_lp_4        ; repeat loop for all possible
  988.                         ; single error remainders
  989.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  990.                         ; and get new remainder in x0
  991.         teq    y0,a    r0,r2        ; if equal, make sure a is not
  992.                         ; cleared and store remainder
  993.                         ; pointer value
  994. bas_fix_lp_4    move    #bas_error_fix_5,r0    ; default next state
  995.         tst    a    x:(r2+5),a    ; has error been located ?
  996.                         ; get error correct mask in a 
  997.         beq    <end_check_4        ; if a is clear, error not found
  998.                         ; go to next search state
  999.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  1000.                         ; state
  1001.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1002. end_check_4    rts                
  1003.         
  1004. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1005.  
  1006. bas_error_fix_5    move    #double_error_3,r0    ; double error check remainders
  1007.         move    x:error_store,b        ; latest error remainder result
  1008.         clr    a    b,y0        ; clear a for loop and ensure y0
  1009.                         ; is not empty.
  1010.         move    x:(r0)+,x0        ; load first ref. in x0 whilst 
  1011.                         ; updating the remainder pointer
  1012.         do     #7,bas_fix_lp_5        ; repeat loop for every possible
  1013.                         ; single error remainder
  1014.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1015.                         ; and get new remainder in x0
  1016.         teq    y0,a    r0,r2        ; if equal, make sure a is not
  1017.                         ; cleared and store remainder
  1018.                         ; pointer value
  1019. bas_fix_lp_5    move    #bas_error_fix_6,r0    ; default next state
  1020.         tst    a    x:(r2+5),a    ; has error been located ?
  1021.                         ; put error correct mask in a 
  1022.         beq    <end_check_5        ; if a is clear, error not found
  1023.                         ; go to next search state
  1024.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  1025.                         ; state
  1026.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1027. end_check_5    rts                
  1028.         
  1029. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1030.  
  1031. bas_error_fix_6    move    #error_0001_mask,r0    ; single error check remainders
  1032.         move    x:error_store,b        ; latest error remainder result
  1033.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1034.         move    x:(r0)+,x0        ; load first ref. in x0 whilst 
  1035.                         ; updating the remainder pointer
  1036.         do     #8,bas_fix_lp_6        ; repeat loop for all possible
  1037.                         ; single error remainders
  1038.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1039.                         ; and get new remainder in x0
  1040.         teq    y0,a            ; if equal, correction mask in a
  1041.  
  1042. bas_fix_lp_6    move    #bas_error_fix_7,r0    ; default next state    
  1043.         tst    a            ; has error been located ?
  1044.         beq    <end_check_6        ; if a is clear, error not found
  1045.                         ; go to next search state
  1046.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  1047.                         ; state
  1048.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1049. end_check_6    rts                
  1050.         
  1051. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1052.  
  1053. bas_error_fix_7    move    #error_0002_mask,r0    ; single error check remainders
  1054.         move    x:error_store,b        ; latest error remainder result
  1055.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1056.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1057.                         ; updating the remainder pointer
  1058.         do     #8,bas_fix_lp_7        ; repeat loop for all possible
  1059.                         ; single error remainder
  1060.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1061.                         ; and get new remainder in x0
  1062.         teq    y0,a            ; if equal, correction mask in a  
  1063. bas_fix_lp_7    move    #bas_error_fix_8,r0    ; default next state    
  1064.         tst    a            ; has error been located ?
  1065.         beq    <end_check_7        ; if a is clear, error not found
  1066.                         ; go to next search state
  1067.         move    #bas_valid_tst_0,r0    ; a has data, error fix next 
  1068.                         ; state
  1069.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1070. end_check_7    rts                
  1071.         
  1072. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1073.  
  1074. bas_error_fix_8    move    #error_0004_mask,r0    ; single error check remainders
  1075.         move    x:error_store,b        ; latest error remainder result
  1076.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1077.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1078.                         ; updating the remainder pointer
  1079.         do     #8,bas_fix_lp_8        ; repeat loop for all possible
  1080.                         ; single error remainders
  1081.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1082.                         ; and get new remainder in x0
  1083.         teq    y0,a            ; if equal, correction mask in a  
  1084. bas_fix_lp_8    move    #bas_error_fix_9,r0    ; default next state    
  1085.         tst    a            ; has error been located ?
  1086.         beq    <end_check_8        ; if a is clear, error not found
  1087.                         ; go to next search state
  1088.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  1089.                         ; state
  1090.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1091. end_check_8    rts                
  1092.         
  1093. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1094.  
  1095. bas_error_fix_9    move    #error_0008_mask,r0    ; single error check remainders
  1096.         move    x:error_store,b        ; latest error remainder result
  1097.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1098.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1099.                         ; updating the remainder pointer
  1100.         do     #8,bas_fix_lp_9        ; repeat loop for all possible
  1101.                         ; single error remainders
  1102.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1103.                         ; and get new remainder in x0
  1104.         teq    y0,a            ; if equal, correction mask in a  
  1105. bas_fix_lp_9    move    #bas_err_fix_10,r0    ; default next state    
  1106.         tst    a            ; has error been located ?
  1107.         beq    <end_check_9        ; if a is clear, error not found
  1108.                         ; go to next search state
  1109.         move    #bas_valid_tst_0,r0    ; a has data, error fix next
  1110.                         ; state
  1111.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1112. end_check_9    rts
  1113.         
  1114. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1115.  
  1116. bas_err_fix_10    move    #error_0010_mask,r0    ; single error check remainders
  1117.         move    x:error_store,b        ; latest error remainder result
  1118.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1119.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1120.                         ; updating the remainder pointer
  1121.         do     #8,bas_fix_lp_10    ; repeat loop for every possible
  1122.                         ; single error remainder
  1123.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1124.                         ; and get new remainder in x0
  1125.         teq    y0,a            ; if equal, correction mask in a  
  1126. bas_fix_lp_10    move    #bas_err_fix_11,r0    ; default next state    
  1127.         tst    a            ; has error been located ?
  1128.         beq    <end_check_10        ; if a is clear, error not found
  1129.                         ; go to next search state
  1130.         move    #bas_valid_tst_0,r0    ; a has data, error fix next 
  1131.                         ; state
  1132.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1133. end_check_10    rts
  1134.         
  1135. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1136.  
  1137. bas_err_fix_11    move    #error_0020_mask,r0    ; single error check remainders
  1138.         move    x:error_store,b        ; latest error remainder result
  1139.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1140.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1141.                         ; updating the remainder pointer
  1142.         do     #8,bas_fix_lp_11    ; repeat loop for every possible
  1143.                         ; single error remainder
  1144.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1145.                         ; and get new remainder in x0
  1146.         teq    y0,a            ; if equal, correction mask in a  
  1147. bas_fix_lp_11    move    #bas_err_fix_12,r0    ; default next state    
  1148.         tst    a            ; has error been located ?
  1149.         beq    <end_check_11        ; if a is clear, error not found
  1150.                         ; go to next search state
  1151.         move    #bas_valid_tst_0,r0    ; a has data, error fix next 
  1152.                         ; state
  1153.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1154. end_check_11    rts
  1155.         
  1156. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1157.  
  1158. bas_err_fix_12    move    #error_0040_mask,r0    ; single error check remainders
  1159.         move    x:error_store,b        ; latest error remainder result
  1160.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1161.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1162.                         ; updating the remainder pointer
  1163.         do     #8,bas_fix_lp_12    ; repeat loop for every possible
  1164.                         ; single error remainder
  1165.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1166.                         ; and get new remainder in x0
  1167.         teq    y0,a            ; if equal, correction mask in a  
  1168. bas_fix_lp_12    move    #bas_err_fix_13,r0    ; default next state    
  1169.         tst    a            ; has error been located ?
  1170.         beq    <end_check_12        ; if a is clear, error not found
  1171.                         ; go to next search state
  1172.         move    #bas_valid_tst_0,r0    ; a has data, error fix next 
  1173.                         ; state
  1174.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1175. end_check_12    rts
  1176.         
  1177. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1178.  
  1179. bas_err_fix_13    move    #control_word,r2    
  1180.         move    #error_0080_mask,r0    ; single error check remainders
  1181.         move    x:error_store,b        ; latest error remainder result
  1182.         clr    a    x:(r0)+,y0    ; clear a for loop and ensure y0                        ; contains the error mask.
  1183.         move    x:(r0)+,x0        ; load first ref. in x0 whilst
  1184.                         ; updating the remainder pointer
  1185.         do     #8,bas_fix_lp_13    ; repeat loop for every possible
  1186.                         ; single error remainder
  1187.         cmp     x0,b    x:(r0)+,x0    ; check for remainder equality
  1188.                         ; and get new remainder in x0
  1189.         teq    y0,a            ; if equal, correction mask in a
  1190. bas_fix_lp_13    move    #bas_valid_tst_0,r0    ; default next state
  1191.         bfset    #$0020,x:(r2)        ; default BAS correct indicator
  1192.                         ; in control word
  1193.         move    a1,x:error_mask        ; store relevant error correct                            ; mask
  1194.         tst    a            ; has error been located ?
  1195.         bne    <end_check_13        ; if a is clear, error not found
  1196.  
  1197.         move    #bas_fix_end,r0
  1198.         bfclr    #$0020,x:(r2)         ; and current BAS is invalid
  1199.  
  1200. end_check_13    rts
  1201.  
  1202. ;;*****************************************************************************
  1203. ;;*                                          *
  1204. ;;*    Multiframe and Frame alignment test states    :      This state    *
  1205. ;;*    is used to check whether the latest received and decoded BAS signal   *
  1206. ;;*    should be validated. In order to do this we must check for frame and  *
  1207. ;;*    multiframe alignment and that the Frame alignment signal in the same  *
  1208. ;;*    submultiframe has fewer than 2 bits in error. If either of these      *
  1209. ;;*     conditions are not met then the current decoded BAS is ignored.          *
  1210. ;;*                                          *
  1211. ;;*    Date    :    4/10/90                              *
  1212. ;;*    Version    :    1.0                              *
  1213. ;;*                                          *
  1214. ;;*****************************************************************************
  1215.  
  1216. bas_valid_tst_0    move    x:bas_erc_faw_ptr,r2    ; get latest H221 word pointer
  1217.         move    #bas_valid_tst_1,r0    ; next state
  1218.                             
  1219.         clr    b    x:(r2-1),x0    ; clear b and y for state and
  1220.         tfr3    b,y0    x:(r2)+,x1    ; get EVEN frame H221 word,
  1221.                         ; and update pointer
  1222.         bftstl    #$0002,x0        ; faw bit 0, should be low
  1223.         adc    y,b            ; add carry to correct bit count
  1224.         bftstl    #$0004,x0        ; faw bit 1, should be low
  1225.         adc    y,b            ; add carry to correct bit count
  1226.         bftsth    #$0008,x0        ; faw bit 2, should be high
  1227.         adc    y,b            ; add carry to correct bit count
  1228.         bftsth    #$0010,x0        ; faw bit 3, should be high
  1229.         adc    y,b            ; add carry to correct bit count
  1230.         bftstl    #$0020,x0        ; faw bit 4, should be low
  1231.         adc    y,b            ; add carry to correct bit count
  1232.         bftsth    #$0040,x0        ; faw bit 5, should be high
  1233.         adc    y,b            ; add carry to correct bit count
  1234.         bftsth    #$0080,x0        ; faw bit 6, should be high
  1235.         adc    y,b            ; add carry to correct bit count
  1236.         bftsth    #$0002,x1        ; faw bit 7, should be high
  1237.         adc    y,b            ; add carry to correct bit count
  1238.  
  1239.         move    b0,x:faw_true_bit_cnt    ; store the correct bit count
  1240.         move    r2,x:bas_erc_faw_ptr    ; store updated pointer
  1241.         
  1242.         rts
  1243.  
  1244. bas_valid_tst_1    move    #control_word,r2    ; get control word
  1245.         move    #bas_fix_end,r0        ; next state
  1246.         
  1247.         bfclr    #$0020,x:(r2)        ; set BAS invalid indicator
  1248.                         ; in control word
  1249.         move    x:faw_true_bit_cnt,b    ; get the correct bit count in b
  1250.         movei    #6,x0            ; is correct bit count greater
  1251.         cmp    x0,b            ; than or equal to 6 ?
  1252.         ble    <bas_invalid        ; if less than 6 then bas is 
  1253.                         ; invalid.
  1254.         bftsth    #$6000,x:(r2)        ; test for frame AND multiframe
  1255.         bcc    <bas_invalid        ; alignment, branch if not OK
  1256.         
  1257.         bfset    #$0020,x:(r2)        ; set BAS valid indicator 
  1258.         
  1259. bas_invalid    rts
  1260.         
  1261. ;;***********************************************************************
  1262. ;;*                                    *
  1263. ;;*    BAS Fix End State    :    This state checks the        *
  1264. ;;*     control word for whether the BAS invalid flag is asserted    *
  1265. ;;*    and subsequently either updates the latest decoded BAS        *
  1266. ;;*     signal or ignores the current received BAS as a result.        *
  1267. ;;*                                    *
  1268. ;;*    Date    :    12/10/90                    *
  1269. ;;*    Version    :    1.0                        *
  1270. ;;*                                    *
  1271. ;;***********************************************************************
  1272.  
  1273. bas_fix_end    move    #smf_state_0,r0        ; next state
  1274.         move    x:control_word,x1    ; if the current received bas
  1275.         bftsth    #$0020,x1        ; is not valid then do nothing
  1276.         bcc    <bas_not_true
  1277.         
  1278.         move    x:decoded_bas_ptr,r3    ; recall current BAS pointer
  1279.         move    m3,x:decoded_bas_ptr    ; save current m3 value
  1280.         move    #7,m3            ; modulo 8 buffer
  1281.         move    x:error_mask,x0        ; get error mask
  1282.         move    x:(r3),b        ; get latest decoded BAS
  1283.         eor    x0,b            ; change incorrect bits in
  1284.         move    b1,x:(r3)+        ; received bas, store and update
  1285.                         ; pointer
  1286.         move    x:decoded_bas_ptr,m3    ; restore m3 value
  1287.         move    r3,x:decoded_bas_ptr    ; BAS pointer for next time and
  1288.                         ; store new value                
  1289. bas_not_true    rts
  1290.         
  1291. ;;***************************************************************************
  1292. ;;*                                        *
  1293. ;;*    BAS Revert State    :     The function of this state is        * 
  1294. ;;*    to reset the latest decoded BAS word to its 3'rd previous value     *
  1295. ;;*    after frame alignment has been lost.                    *
  1296. ;;*                                            *
  1297. ;;*    Date    :    4/10/90                            *
  1298. ;;*    Version    :    1.0                                *
  1299. ;;*                                        *
  1300. ;;***************************************************************************
  1301.  
  1302. bas_revert    move    x:decoded_bas_ptr,r3    ; last decoded BAS pointer
  1303.         move    m3,x:decoded_bas_ptr    ; store current value of r3
  1304.         move    #7,m3            ; set m3 for modulo 8 addressing
  1305.                         ; i.e. 8 word circular buffer
  1306.         move    #bf_state_0,r0        ; next state
  1307.         lea    (r3)-,r3        ; set decoded BAS(n) to BAS(n-1)
  1308.                         ; as last valid BAS pointer
  1309.         move    x:decoded_bas_ptr,m3    ; restore last m3 register value
  1310.         move    r3,x:decoded_bas_ptr    ; 3'rd last decoded BAS word
  1311.  
  1312.         rts
  1313.  
  1314. ;;***************************************************************************
  1315. ;;*                                        *
  1316. ;;*    CRC performance check for the ISDN 64 kbps channel            *
  1317. ;;*    Data structure used ;                            *
  1318. ;;*                                        *
  1319. ;;*   |       a1       |            a1           |        a0           |  *
  1320. ;;*                                        *
  1321. ;;*    0  0  0  y     x xd1xd2xd3xd4xd5xd6xd7    x xd1xd2xd3xd4xd5xd6xd7    *
  1322. ;;*              *           *                            *
  1323. ;;*   output states    penultimate ISDN data         last data rx        *
  1324. ;;*          y             ir(N-1)                 ir(N)              *
  1325. ;;*                                        *
  1326. ;;*        d     == single state delay                    *
  1327. ;;*        *     == bits to be x'ored                    *
  1328. ;;*        y4    == output and crc result msb                *
  1329. ;;*        @    == after next clock i.e. next left shift        *
  1330. ;;*                                        *
  1331. ;;*    Equations governing the crc operation are as below :            *
  1332. ;;*                                          *
  1333. ;;*        @ x    ==     y + xd1                       *
  1334. ;;*        @ xd3    ==    y + xd4                        *
  1335. ;;*                                        *
  1336. ;;*    The CRC equation for the ISDN line check is    :            *
  1337. ;;*                                              *
  1338. ;;*        y(d)/x(d) == g(d) == d4/(1+d+d4)                 *
  1339. ;;*                                        *
  1340. ;;*        Date    :    27/9/90                        *
  1341. ;;*                29/4/91                     *
  1342. ;;*        Version    :    1.8                        *
  1343. ;;*                1.9                        *
  1344. ;;*                                          *
  1345. ;;***************************************************************************
  1346.  
  1347. ;;  Optimised storage set_up  :            isdn_count_rx    ds    1
  1348. ;;                        rx_crc_store    ds    1
  1349. ;;                                dc    0
  1350. ;;                                dc    8
  1351. ;;                        ir_shft        ds    1
  1352. ;;                        rx_crc_value_2    dc    12
  1353. ;;                                dc    $0090
  1354. ;;                        rx_crc_data    ds    1
  1355.  
  1356. crc_rx        move    #isdn_count_rx,r3    ; optimised storage pointer
  1357.         move    x:rx_crc_cnt_ptr,r2    ; crc count comparison pointer
  1358.  
  1359.         move    x:(r3)+,b        ; current isdn count in b
  1360.         move    x:(r3)+,a        ; last crc storage value in a
  1361.         move    x:(r3)+,y0        ; zero ref. count in y0
  1362.         move    x:(r2)+n2,x1 x:(r3)+,x0    ; current reference count in x1
  1363.                         ; default loop count in x0
  1364.         cmp    x1,b    x:(r2+50),x1    ; first byte of new smf ?
  1365.                         ; last byte of smf, count in x1
  1366.         bne    <rx_smf_not_done
  1367.         cmp    y0,b    x:(r2)+,y1    ; first byte of multiframe ?
  1368.                         ; update reference counter in y1
  1369.         bne    <rx_cnt_not_zero    ; no, then branch
  1370.  
  1371.         move    #crc_count,r2        ; yes, restore count pointer,
  1372.  
  1373. rx_cnt_not_zero    move    a1,x:rx_crc_data    ; store final crc result,
  1374.         move    x:ir,a            ; isdn data in a1 lower byte
  1375.                         ; this provides the d4 multiply 
  1376.         bra    <crc_loop_rx        ; function in crc generator eqn.
  1377.                         ; wait for next intrupt for crc
  1378. rx_smf_not_done    move    x:(r3)+,a0        ; new isdn data in here to a0
  1379.         move    x:(r2+34),y1        ; crc bit rx, lower window count
  1380.         cmp    y1,b    x:(r2+42),y1    ; current isdn count in window ?
  1381.         blt    <out_window_rx        ; no, then branch
  1382.         cmp    y1,b            ; current isdn count in window ?
  1383.         bgt    <out_window_rx        ; no, then branch
  1384.  
  1385.         bfclr    #$0100,a0        ; if in window, clear last isdn
  1386.                         ; rx lsb before executing crc
  1387. out_window_rx    cmp    x1,b    x:(r3)+,y0    ; last count in present block ?
  1388.                         ; update pointer for next time.
  1389.         tne    x0,b            ; appropriate loop count
  1390.         teq    y0,b            ; in b1
  1391.         swap    b            ; loop count in b0
  1392.         tfr3    b,y0    x:(r3)+,x0    ; clear y0 for crc loop, 
  1393.                         ; crc mask 2 in x0
  1394.         do    b0,crc_loop_rx        ; do loop b0 times
  1395.  
  1396.         bfclr    #$0080,a1        ; test last output,
  1397.         tcc    x0,b            ; set mask as a result of test
  1398.         asl    a    b,y1        ; mask in y1, shift bits for eor
  1399.         eor    y1,a    y0,b        ; perform modulo 2 of a1 bits 
  1400.                         ; and clear b
  1401. crc_loop_rx    move    a1,x:rx_crc_store    ; save CRC data for next rx
  1402.         move    r2,x:rx_crc_cnt_ptr    ; save reference count pointer
  1403.  
  1404.         rts
  1405.  
  1406.         nolist